Linux下 C语言路由器项目(纯C 1K代码,适合练手,也可写在简历上面 )

您所在的位置:网站首页 linux 软路由软件 Linux下 C语言路由器项目(纯C 1K代码,适合练手,也可写在简历上面 )

Linux下 C语言路由器项目(纯C 1K代码,适合练手,也可写在简历上面 )

2024-04-10 14:22| 来源: 网络整理| 查看: 265

一.项目流程图

二.环境搭建

主机:

Ubuntu:

设置网络:

开发板: 设置IP:ifconfig eth0 192.168.2.1 netmask 255.255.255.0 设置网关:route add  default gw 192.168.2.2

实践:

主机与虚拟机相互ping

成功:

开发板与主机相互ping

失败:(因为是不同网段)

ok,完成

最后,运行我们写的路由器代码后,主机与开发板可以在不同网段下通信

开发板与主机相互ping

成功:

三.遇到的问题

1.默认网关有问题,导致开发板ping不通wind主机,后重启开发板后重新添加默认网关解决

异常(ping不通)

正常(可ping通)

2.wind的默认网关填错,导致ping不通开发板,这里的默认网关是根据虚拟机里面网卡来填的,需要灵活变动。

3.在虚拟机里面是需要2个网卡都能使用,在virtualbox只能有一个网卡可以down和up,所以环境一直有问题

成功互相ping通

四.代码如下:

Makefile

CC=gcc target=main $(target):main.o get_interface.o link.o -lpthread $(CC) main.o get_interface.o link.o -o $(target) -lpthread %*.o:%*.c $(CC) -c $^ -o $@ clean: rm -rf *.o $(target)

main.c

#include #include #include #include #include #include #include #include #include "get_interface.h" #include "link.h" MY_ROU * roulink_head = NULL; MY_ARP * arplink_head = NULL; int sockfd = 0; //*************************人机交互线程********************************** void *callback1(void *arg) { while(1) { printf("输入相应的序号,实现对应功能\n"); int usercmd = -1; scanf("%d", &usercmd); switch (usercmd) { case 0: getchar(); title(); break; case 2: getchar();//接收输入2的回车 roulink_head=rou_pTailInsert(roulink_head); break; case 3: getchar(); roulink_head=rou_pDeleteLink(roulink_head); break; case 4: getchar(); rou_print_link(roulink_head);/*将指针pHead传入输出函数遍历输出*/ printf("链表打印完毕!\n"); break; case 5: arp_print_link(arplink_head); break; case 10: printf("10:退出路由器,释放IP、ARP链表\n"); getchar(); arp_freeLink(arplink_head); rou_freeLink(roulink_head);//释放链表 exit(1); break; } } pthread_exit(NULL); } //*************************人机交互线程********************************** //*************************ARP应答的IP和MAC存入缓存链表线程【开始】**************// void * callback2_arp(void *arg) { arp_mac_ip *p = (arp_mac_ip*)arg; //printf("将 ARP 应答的 IP 和 MAC 存入缓存链\n"); //printf("### %s\n", p->stc_ip); if(arp_searcharpLink(arplink_head, p->stc_ip) == 0) { printf("插入链表中没有的ARP 应答 IP 和 MAC\n"); arplink_head = arp_pTailInsert( arplink_head, p->stc_mac ,p->stc_ip); } pthread_exit(NULL); } //*************************ARP应答的IP和MAC存入缓存链表线程【结束】***************// //*************************IP包转发线程【开始】**********************************// void *callback3_ip(void *arg) { //发送接口的结构体 struct sockaddr_ll sll; ip_buf *pthread_ip_buf = (ip_buf *)arg; unsigned char * ip_head= pthread_ip_buf->buf + 14; char dst_ip[16] = ""; inet_ntop(AF_INET, ip_head + 16, dst_ip, 16); printf("IP包转发线程中 目的 dst_ip = %s\n", dst_ip); int i = 0; for (i = 0; i < 16; i++) { unsigned char ip[16]=""; inet_ntop(AF_INET,net_interface[i].ip, ip, 16);//get_interface文件中得到的都是32位无符号整形数据(计算机数据),现转成成点分十进制(人能够书别的) //---------------------[调试]----------------------------------------// //printf("设置网卡循环进入次数 i = %d\n", i); //printf("检索到的所有网卡名字net_interface[i].name = %s\n", net_interface[i].name); //printf("net_interface[i].ip = %s\n",ip); //---------------------[调试]----------------------------------------// if(strncmp(ip, dst_ip, 9) == 0)//根据目标网段 查找活跃网卡 { //网卡结构体 struct ifreq ethreq; strncpy(ethreq.ifr_name, net_interface[i].name , IFNAMSIZ);//指定网卡名字 printf("网卡名字:%s\n", ethreq.ifr_name); if(ioctl(sockfd, SIOCGIFINDEX, ðreq) == -1)//获取网卡接口地址 { return 0; } bzero(&sll, sizeof(sll)); sll.sll_ifindex = ethreq.ifr_ifindex;//将网卡的接口类型赋值给发送接口 break; } else { //printf("找不到网段对应的网卡,继续查\n"); continue; } } //--------------------------------------------拿到网卡,开始检索对应网卡所有数据,对比【开始】------------------------------------------------------// if(strcmp(dst_ip + strlen(dst_ip) - 3, "255") == 0)//是 否为广 播地址 { // printf("是广播地址, 退出线\n"); return; } else { //printf("不是广播地址,判断是否为回 环地址\n"); if(strcmp("127.0.0.1", dst_ip) == 0) { //printf("是回 环地址, 退出线\n"); return; } else { //printf("查找ARP缓存表 对应 MAC\n"); //指定目的MAC地址 //可以在链表中找到目的IP,组ICMP包的目的MAC就可以了 //之所以这样,是因为在网络中的ICMP包里,变化的只有目的MAC,源MAC、IP都不会发生变动 if(arp_searcharpLink(arplink_head, dst_ip) == 1) { //1网段中 指定目标IP是主机的IP、MAC //2C-4D-54-57-04-7F //printf("****icmp****\n"); if(strncmp("192.168.1.49", dst_ip, 9) == 0) { pthread_ip_buf->buf[0]=0x2C; pthread_ip_buf->buf[1]=0x4D; pthread_ip_buf->buf[2]=0x54; pthread_ip_buf->buf[3]=0x57; pthread_ip_buf->buf[4]=0x04; pthread_ip_buf->buf[5]=0x7F;//目标 int send_len = sendto(sockfd, pthread_ip_buf->buf, pthread_ip_buf->my_buf_date_len, 0, (struct sockaddr *)&sll, sizeof(sll)); //-------------------[调试]------------------------// //printf("****1 网段 icmp缓存表****\n"); // printf("send_len ICMP 1 = %d\n", send_len); //-------------------[调试]------------------------// } //2网段中 指定目标IP是开发板的IP、MAC // 00:53:50:00:01:33 else if(strncmp("192.168.2.100", dst_ip, 9) == 0) { pthread_ip_buf->buf[0]=0x00; pthread_ip_buf->buf[1]=0x53; pthread_ip_buf->buf[2]=0x50; pthread_ip_buf->buf[3]=0x00; pthread_ip_buf->buf[4]=0x59; pthread_ip_buf->buf[5]=0x12; //发送给套接字的数据长度,是实际传送过来的长度(main中的IP包有收到具体长度信息) int send_len = sendto(sockfd, pthread_ip_buf->buf, pthread_ip_buf->my_buf_date_len, 0, (struct sockaddr *)&sll, sizeof(sll)); //-------------------[调试]------------------------// //printf("****2 网段 icmp缓存表****\n"); // printf("send_len ICMP 2 = %d\n", send_len); //-------------------[调试]------------------------// } } else {//没在链表中没有找到目的IP,需要重新组arp包才行 //printf("***************组ARP包\n"); int i = 0; for(; i < 3; i++) { //printf("%s\n",dst_ip); //比对到1网段的数据 if(strstr(dst_ip,"192.168.1") != 0) { printf("发送网段1arp包\n"); unsigned char arp_buf[42] = { 0xff,0xff,0xff,0xff,0xff,0xff,//目的mac,广播的形式发出去,等待目的IP恢复后覆盖 0x00,0x0c,0x29,0xfa,0x7c,0x9e,//源mac 0x08, 0x00,//协议类型 0, 1,//硬件类型 6, 4, 0, 1,//op 0x00,0x0c,0x29,0xfa,0x7c,0x9e,//源mac(网卡1 ech0的MAC) 192,168,1,88,//源IP是路由器1网段的网关,通过它发送到2网段 0x00,0x00,0x00,0x00,0x00,0x00,//目的mac,等待目的IP恢复后覆盖 0,0,0,0 //192,168,1,49, }; int int_ip=0; inet_pton(AF_INET, dst_ip, &int_ip); unsigned char *intp=(char *)&int_ip; arp_buf[38]=intp[0]; arp_buf[39]=intp[1]; arp_buf[40]=intp[2]; arp_buf[41]=intp[3]; int send_len = sendto(sockfd, arp_buf, sizeof(arp_buf), 0, (struct sockaddr *)&sll, sizeof(sll)); printf("send_len 11 = %d\n",send_len); } //网卡2,ech1的MAC:00:0c:29:fa:7c:a8 else if(strstr(dst_ip,"192.168.2") != 0) { printf("发送网段2arp包\n"); unsigned char arp_buf[42] = { 0xff,0xff,0xff,0xff,0xff,0xff,//目的mac 0x00,0x0c,0x29,0xfa,0x7c,0xa8,//源mac 0x08, 0x00,//协议类型 0, 1,//硬件类型 6, 4, 0, 1,//op 0x00,0x0c,0x29,0xfa,0x7c,0xa8,//源mac 192,168,2,89,//源IP是路由器2网段的网关,通过它发送到1网段 0x00,0x00,0x00,0x00,0x00,0x00,//目的mac 192,168,2,100, }; int send_len = sendto(sockfd, arp_buf, sizeof(arp_buf), 0, (struct sockaddr *)&sll, sizeof(sll)); printf("send_len 22 = %d\n",send_len); } if(arp_searcharpLink(arplink_head, dst_ip) == 1) { //1 //2C-4D-54-57-04-7F if(strncmp("192.168.0.11", dst_ip, 9) == 0) { pthread_ip_buf->buf[0] = 0xA8; pthread_ip_buf->buf[1] = 0x5E; pthread_ip_buf->buf[2] = 0x45; pthread_ip_buf->buf[3] = 0xC1; pthread_ip_buf->buf[4] = 0x8B; pthread_ip_buf->buf[5] = 0x99; int send_len = sendto(sockfd, pthread_ip_buf->buf, pthread_ip_buf->my_buf_date_len, 0, (struct sockaddr *)&sll, sizeof(sll)); //-------------------[调试]------------------------// //printf("****3次发ARP过程中检索到ICMP包 1 网段****\n"); // printf("send_len ICMP 1 = %d\n", send_len); //-------------------[调试]------------------------// } //2 // 开发板MAC(每次启动都会变化):1C:59:74:81:4A:43 1C:59:74:81:4A:43 else if(strncmp("192.168.1.1", dst_ip, 9) == 0) { pthread_ip_buf->buf[0] = 0x1c; pthread_ip_buf->buf[1] = 0x59; pthread_ip_buf->buf[2] = 0x74; pthread_ip_buf->buf[3] = 0x81; pthread_ip_buf->buf[4] = 0x4A; pthread_ip_buf->buf[5] = 0x43; int send_len = sendto(sockfd, pthread_ip_buf->buf, pthread_ip_buf->my_buf_date_len, 0, (struct sockaddr *)&sll, sizeof(sll)); //-------------------[调试]------------------------// //printf("****3次发ARP过程中检索到ICMP包 2 网段****\n"); // printf("send_len ICMP 2 = %d\n", send_len); //-------------------[调试]------------------------// } break; } } } return; } } //--------------------------------------------拿到网卡,开始检索对应网卡所有数据,对比【结束】------------------------------------------------------// pthread_exit(NULL); } //*************************建IP包转发线程【结束】**********************************// int main() { //创建原始套接字,接收发送方的网卡信息 sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); if(sockfdbuf, recv_buff, recv_len); //线程的创建放在满足它的条件中,while循环,满足就进来创建一个,切记不要放到条件外面创建线程,否则只会创建一个,导致所有情况共用一个线程 pthread_t pth2; //最后数据包是ICMP的整包 pthread_create(&pth2, NULL, callback3_ip, (void*)recv); pthread_detach(pth2); } } } else if(mac_type == 0x0806) { arp_mac_ip * head_mac_ip = NULL;//保存目的MAC\IP的结构体,安全措施,防止栈空间释放导致给线程传参为空,失败 head_mac_ip = (arp_mac_ip *)malloc(sizeof(arp_mac_ip )); unsigned char *arp_head = recv_buff + 14; unsigned char * arp_src_mac = arp_head + 8;//跳过[4.硬件类型、5.协议类型、6.硬件地址长度、7.协议地址长度、8.OP,拿到源MAC地址首地址信息] unsigned char stc_mac[18] = ""; sprintf(stc_mac, "%02x:%02x:%02x:%02x:%02x:%02x", arp_src_mac[0],\ arp_src_mac[1],\ arp_src_mac[2], \ arp_src_mac[3],\ arp_src_mac[4], \ arp_src_mac[5]); strcpy(head_mac_ip->stc_mac, stc_mac); unsigned char src_ip[16] = ""; inet_ntop(AF_INET, arp_head + 14, src_ip, 16);//拿到源IP strcpy(head_mac_ip->stc_ip, src_ip); //-----------------------------------[调试]-----------------------------------// //printf("-----------arp数据包------------\n"); //printf("arp 源mac:%s\n",head_mac_ip->stc_mac); //printf("arp 源IP:src_ip = %s \n", src_ip); //-----------------------------------[调试]-----------------------------------// //线程中只保存源ARP的MAC、IP,目的主机的MAC、IP,在IP线程中指定(写死) pthread_t pth1; pthread_create(&pth1, NULL, callback2_arp, (void*)head_mac_ip); pthread_detach(pth1); } } return 0; }

link.c

#include "link.h" void title() { printf("[人机交互线程的全部功能]\n"); printf("2:设置过滤 IP \n"); printf("3:删除过滤 IP \n"); printf("4:查看过滤 IP \n"); printf("5:查看 arp 缓存 \n"); printf("10:退出路由器\n"); } //*************************过滤链表****************************** //尾插 MY_ROU *rou_pTailInsert(MY_ROU *head) { //申请一个待插入的空间 MY_ROU *pi=(MY_ROU*)malloc(sizeof(MY_ROU)); pi->next=NULL; printf("输入过滤ip:"); //向空间中插入数据 scanf("%s",pi->ip); //判断是否有数据 if(head==NULL) { head=pi; } else { //寻找插入的节点 MY_ROU *p1=head; while(p1->next!=NULL) { p1=p1->next; } //插入 p1->next=pi; } printf("设置完成\n"); return head; } //遍历 void rou_print_link(MY_ROU *head) { if(head==NULL) { printf("没有数据\n"); } else { while(head!=NULL) { printf("ip:%s\n",head->ip); head=head->next; } } return; } //释放链表 MY_ROU* rou_freeLink(MY_ROU *head) { MY_ROU *pd; pd=head; while(head!=NULL) { head=pd->next; free(pd); pd=head; } printf("过滤链表释放完毕\n"); return head; } //查找ip int rou_searcharpLink(MY_ROU *head,char *ip) { int i=0; while(head!=NULL) { if(strcmp(ip,head->ip)==0) { i++; //printf("存在相同ip\n"); return 1; } head=head->next; } if(0==i) { //printf("未找到ip\n"); return 0; } } //删除 MY_ROU *rou_pDeleteLink(MY_ROU *head) { char num[16]=""; MY_ROU *pe=head; MY_ROU *pf=head; printf("请输入你要删除的ip:"); scanf("%s",num); if(NULL==head) { printf("无可删除数据\n"); } else { while(strcmp(pe->ip,num)) { pf=pe; pe=pe->next; if(NULL==pf->next) { printf("未找到要删除数据\n"); return head; } } if(pe==head) { head=pe->next; free(pe); } else { pf->next=pe->next; free(pe); } } return head; } //*************************过滤链表****************************** //*************************arp缓存表***************************** //arp缓存表尾插 MY_ARP *arp_pTailInsert(MY_ARP *head,char *mac,char *ip) { //申请一个待插入的空间 MY_ARP *pi=(MY_ARP*)malloc(sizeof(MY_ARP)); pi->next=NULL; //向空间中插入数据 strcpy(pi->ip,ip); strcpy(pi->mac,mac); //判断是否有数据 if(head==NULL) { head=pi; } else { //寻找插入的节点 MY_ARP *p1=head; while(p1->next!=NULL) { p1=p1->next; } //插入 p1->next=pi; } printf("插入一个ip:%s mac:%s 到arp缓存表\n",pi->ip,pi->mac); return head; } //arp中查找ip和mac int arp_searcharpLink(MY_ARP *head,char *ip) { int i=0; while(head!=NULL) { if(strcmp(ip,head->ip)==0) { i++; //printf("存在相同ip和mac\n"); return 1; } head=head->next; } if(0==i) { //printf("未找到ip和mac\n"); return 0; } } //遍历arp缓存表 void arp_print_link(MY_ARP *head) { if(head==NULL) { printf("没有数据\n"); } else { while(head!=NULL) { printf("ip:%s mac:%s\n",head->ip,head->mac); head=head->next; } } return; } //释放arp链表 MY_ARP* arp_freeLink(MY_ARP *head) { MY_ARP *pd; pd=head; while(head!=NULL) { head=pd->next; free(pd); pd=head; } printf("arp链表释放完毕\n"); return head; } //*************************arp缓存表*****************************

link.h

#include #include #include #define RECV_SIZE 2048 typedef struct My_buf { unsigned char buf[RECV_SIZE]; int my_buf_date_len; }ip_buf; typedef struct Arp_mac_ip { char stc_mac[18]; char stc_ip[16]; }arp_mac_ip; extern void title(); //*************************arp缓存表***************************** typedef struct myarp { unsigned char mac[32] ; unsigned char ip[32] ; struct myarp* next; }MY_ARP; //arp缓存表尾插 extern MY_ARP *arp_pTailInsert(MY_ARP *head,char *mac,char *ip); //arp中查找ip extern int arp_searcharpLink(MY_ARP *head,char *ip); //遍历arp缓存表 extern void arp_print_link(MY_ARP *head); //释放arp链表 extern MY_ARP* arp_freeLink(MY_ARP *head); //*************************arp缓存表***************************** //*************************过滤链表****************************** typedef struct myrouter { unsigned char ip[32] ; struct myrouter* next; }MY_ROU; //释放链表 extern MY_ROU* rou_freeLink(MY_ROU *head); //尾插 extern MY_ROU *rou_pTailInsert(MY_ROU *head); //遍历 extern void rou_print_link(MY_ROU *head); //查找ip extern int rou_searcharpLink(MY_ROU *head,char *ip); //删除 extern MY_ROU *rou_pDeleteLink(MY_ROU *head); //*************************过滤链表******************************

get_interface.c

#include #include #include #include #include #include #include #include #include #include #include #include "get_interface.h" int interface_num=0;//接口数量 INTERFACE net_interface[MAXINTERFACES];//接口数据 /****************************************************************** 函 数: int get_interface_num() 功 能: 获取接口数量 参 数: 无 *******************************************************************/ int get_interface_num(){ return interface_num; } /****************************************************************** 函 数: int getinterface() 功 能: 获取接口信息 参 数: 无 *******************************************************************/ void getinterface() { struct ifreq buf[MAXINTERFACES]; /* ifreq结构数组 */ struct ifconf ifc; /* ifconf结构 */ int sock_raw_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); /* 初始化ifconf结构 */ ifc.ifc_len = sizeof(buf); ifc.ifc_buf = (caddr_t) buf; /* 获得接口列表,所有接口的清单 */ if (ioctl(sock_raw_fd, SIOCGIFCONF, (char *) &ifc) == -1){ perror("SIOCGIFCONF ioctl"); return ; } interface_num = ifc.ifc_len / sizeof(struct ifreq); /* 接口数量 */ printf("interface_num=%d\n\n", interface_num); char buff[20]=""; int ip; int if_len = interface_num; while (if_len-- > 0) { /* 遍历每个接口 */ printf("%s\n", buf[if_len].ifr_name); /* 接口名称 */ sprintf(net_interface[if_len].name, "%s", buf[if_len].ifr_name); /* 接口名称 */ printf("-%d-%s--\n",if_len,net_interface[if_len].name); /* 获得接口标志、flags值 */ if (!(ioctl(sock_raw_fd, SIOCGIFFLAGS, (char *) &buf[if_len]))) { /* 接口状态 */ /*IFF_UP :网络装置是否正常启用,不会因插拔网络线而有任何变化*/ if (buf[if_len].ifr_flags & IFF_UP){ printf("UP\n"); net_interface[if_len].flag = 1; } else{ printf("DOWN\n"); net_interface[if_len].flag = 0; } } else { char str[256]; sprintf(str, "SIOCGIFFLAGS ioctl %s", buf[if_len].ifr_name); perror(str); } /* IP地址 */ if (!(ioctl(sock_raw_fd, SIOCGIFADDR, (char *) &buf[if_len]))) { /*inet_ntoa将一个网络字节序的IP地址(也就是结构体in_addr类型变量) 转化为点分十进制的IP地址(字符串)*/ printf("IP:%s\n",(char*)inet_ntoa(((struct sockaddr_in*) (&buf[if_len].ifr_addr))->sin_addr)); bzero(buff,sizeof(buff)); sprintf(buff, "%s", (char*)inet_ntoa(((struct sockaddr_in*) (&buf[if_len].ifr_addr))->sin_addr)); /*新型网路地址转化函数inet_pton: 将点分十进制的ip地址转化为用于网络传输的数值格式*/ inet_pton(AF_INET, buff, &ip); memcpy(net_interface[if_len].ip, &ip, 4); } else { char str[256]; sprintf(str, "SIOCGIFADDR ioctl %s", buf[if_len].ifr_name); perror(str); } /* 子网掩码 */ if (!(ioctl(sock_raw_fd, SIOCGIFNETMASK, (char *) &buf[if_len]))) { printf("netmask:%s\n",(char*)inet_ntoa(((struct sockaddr_in*) (&buf[if_len].ifr_addr))->sin_addr)); bzero(buff,sizeof(buff)); sprintf(buff, "%s", (char*)inet_ntoa(((struct sockaddr_in*) (&buf[if_len].ifr_addr))->sin_addr)); inet_pton(AF_INET, buff, &ip); memcpy(net_interface[if_len].netmask, &ip, 4); } else { char str[256]; sprintf(str, "SIOCGIFADDR ioctl %s", buf[if_len].ifr_name); perror(str); } /* 广播地址 */ if (!(ioctl(sock_raw_fd, SIOCGIFBRDADDR, (char *) &buf[if_len]))) { printf("br_ip:%s\n",(char*)inet_ntoa(((struct sockaddr_in*) (&buf[if_len].ifr_addr))->sin_addr)); bzero(buff,sizeof(buff)); sprintf(buff, "%s", (char*)inet_ntoa(((struct sockaddr_in*) (&buf[if_len].ifr_addr))->sin_addr)); inet_pton(AF_INET, buff, &ip); memcpy(net_interface[if_len].br_ip, &ip, 4); } else { char str[256]; sprintf(str, "SIOCGIF./ADDR ioctl %s", buf[if_len].ifr_name); perror(str); } /*MAC地址 */ if (!(ioctl(sock_raw_fd, SIOCGIFHWADDR, (char *) &buf[if_len]))) { printf("MAC:%02x:%02x:%02x:%02x:%02x:%02x\n\n", (unsigned char) buf[if_len].ifr_hwaddr.sa_data[0], (unsigned char) buf[if_len].ifr_hwaddr.sa_data[1], (unsigned char) buf[if_len].ifr_hwaddr.sa_data[2], (unsigned char) buf[if_len].ifr_hwaddr.sa_data[3], (unsigned char) buf[if_len].ifr_hwaddr.sa_data[4], (unsigned char) buf[if_len].ifr_hwaddr.sa_data[5]); memcpy(net_interface[if_len].mac, (unsigned char *)buf[if_len].ifr_hwaddr.sa_data, 6); } else { char str[256]; sprintf(str, "SIOCGIFHWADDR ioctl %s", buf[if_len].ifr_name); perror(str); } }//–while end close(sock_raw_fd); //关闭socket }

get_interface.h

#ifndef GET_INTERFACE_H #define GET_INTERFACE_H #define MAXINTERFACES 16 /* 最大接口数 */ typedef struct interface{ char name[20]; //接口名字 unsigned char ip[4]; //IP地址 unsigned char mac[6]; //MAC地址 unsigned char netmask[4]; //子网掩码 unsigned char br_ip[4]; //广播地址 int flag; //状态 }INTERFACE; extern INTERFACE net_interface[MAXINTERFACES];//接口数据 /****************************************************************** 函 数: int getinterface() 功 能: 获取接口信息 参 数: 无 *******************************************************************/ extern void getinterface(); /****************************************************************** 函 数: int get_interface_num() 功 能: 获取实际接口数量 参 数: 接口数量 *******************************************************************/ int get_interface_num(); #endif

ip_file.h

#ifndef IP_FILE_H #define IP_FILE_H #include #include #include #include #include #include //*************************过滤链表****************************** typedef struct myrouter { unsigned char ip[32] ; struct myrouter* next; }MY_ROU; //释放链表 extern MY_ROU* rou_freeLink(MY_ROU *head); //尾插 extern MY_ROU *rou_pTailInsert(MY_ROU *head); //遍历 extern void rou_print_link(MY_ROU *head); //查找ip extern int rou_searcharpLink(MY_ROU *head,char *ip); //删除 extern MY_ROU *rou_pDeleteLink(MY_ROU *head); //*************************过滤链表****************************** /****************************************************************** 函 数: void init_ip_link() 功 能: 读取配置文件数据到链表 参 数: 无 返回值: 无 *******************************************************************/ extern void init_ip_link(); /****************************************************************** 函 数: IP_LINK *find_ip(IP_LINK *head, unsigned char *ip) 功 能: 插入ip过滤链表 参 数: IP_LINK *head ip过滤链表头 IP_LINK* p 待插入节点 返回值: IP_LINK *找到的节点 *******************************************************************/ extern MY_ROU *inner_ip_link(MY_ROU *head,MY_ROU* p); /****************************************************************** 函 数: void save_ip_link() 功 能: 保存链表数据到配置文件 参 数: 无 返回值: 无 *******************************************************************/ extern void save_ip_link(); #endif

 ip_file.c

#include "ip_file.h" #define ip_config_name "ip_config" //与main.c共用一个结构体指针变量,保存过滤IP链表头节点 MY_ROU * roulink_head = NULL; //--------------------操作文件中的过滤IP----------------------// void init_ip_link() { FILE *ip_config = NULL; ip_config = fopen(ip_config_name,"rb+"); if(ip_config == NULL){ perror("!!!configure file,in main.c"); _exit(1); } puts("filter IP:"); int i = 0; while(1) { char buff[500]=""; bzero(buff, sizeof(buff)); int ip; if(fgets(buff, sizeof(buff), ip_config) == NULL) { printf("ip_config 文件为空\n"); break; } if(strlen(buff) < 7)//1.1.1.1 { break; } buff[strlen(buff)-1]=0;//注意文件中存在\r //printf("IP[%d] = %s\n",i++,buff); inet_pton(AF_INET, buff, &ip); MY_ROU *pb = (MY_ROU *)malloc(sizeof(MY_ROU)); char ip_buf[16] = ""; inet_ntop(AF_INET, &ip, ip_buf, 16); //printf("ip_buf[%d] = %s\n", ++i, ip_buf); //strcpy(pb->ip, ip_buf); memcpy(pb->ip, ip_buf, 16); printf("pb->ip[%d] = %s\n", i, pb->ip); //传入变化的头节点 + 带有IP信息的结构体指针变量 roulink_head = inner_ip_link(roulink_head, pb); i++; } //rou_print_link(ip_head); fclose(ip_config); } MY_ROU *inner_ip_link(MY_ROU *head, MY_ROU* p) { // head = (MY_ROU*)malloc(sizeof(MY_ROU)); //创建头结点 // head->next = NULL; MY_ROU * pb = head; int a = rou_searcharpLink(head, p->ip);//查找是否有该记录 if(a == 0) { if(pb==NULL) {//未查找到,插入链表,直接插入表头方便 p->next = NULL; head = p; } else { #if 1 //头插法--寻找插入的节点 MY_ROU * p2_new = (MY_ROU*)malloc(sizeof(MY_ROU)); strcpy(p2_new->ip, p->ip); // printf("继续头插!!!!p2_new->ip = %s!!!!!!\n",p2_new->ip); p2_new->next = pb->next; pb->next = p2_new; #endif #if 0 //尾插法--正确 MY_ROU *p1=pb; while(p1->next!=NULL) { p1=p1->next; } //插入 p1->next=p; #endif } } return head; } void save_ip_link() { FILE *ip_config = fopen(ip_config_name,"wb+"); if(ip_config == NULL){ perror("!!!configure file,in main.c"); _exit(1); } char buff[20]=""; MY_ROU *pb=roulink_head; while(pb != NULL) { printf("!保存2命令输入IP\n"); memcpy(buff, pb->ip, 16);//一次拷贝16个字节 buff[strlen(buff)+1]='\n';//注意文件中存在\r //一个IP新切换一行保存到文件 fprintf(ip_config, "%s\n", buff); pb = pb->next; } fclose(ip_config); } //--------------------操作文件中的过滤IP----------------------// //*************************过滤链表******************************// //尾插 MY_ROU *rou_pTailInsert(MY_ROU *head) { //申请一个待插入的空间 MY_ROU *pi=(MY_ROU*)malloc(sizeof(MY_ROU)); pi->next=NULL; printf("输入过滤ip:"); //向空间中插入数据 scanf("%s",pi->ip); //判断是否有数据 if(head==NULL) { head=pi; } else { //寻找插入的节点 MY_ROU *p1=head; while(p1->next!=NULL) { p1=p1->next; } //插入 p1->next=pi; } printf("设置完成\n"); return head; } //遍历 void rou_print_link(MY_ROU *head) { if(head==NULL) { printf("没有数据\n"); } else { while(head!=NULL) { printf("ip:%s\n",head->ip); head=head->next; } } return; } //释放链表 MY_ROU* rou_freeLink(MY_ROU *head) { MY_ROU *pd; pd=head; while(head!=NULL) { head=pd->next; free(pd); pd=head; } printf("过滤链表释放完毕\n"); return head; } //查找ip int rou_searcharpLink(MY_ROU *head,char *ip) { MY_ROU * pb = head; int i=0; while(pb!=NULL) { if(strcmp(ip, pb->ip)==0) { i++; //printf("存在相同ip\n"); return 1; } pb = pb->next; } if(0==i) { //printf("未找到ip\n"); return 0; } } //删除 MY_ROU *rou_pDeleteLink(MY_ROU *head) { char num[16]=""; MY_ROU *pe=head; MY_ROU *pf=head; printf("请输入你要删除的ip:"); scanf("%s",num); if(NULL==head) { printf("无可删除数据\n"); } else { while(strcmp(pe->ip,num)) { pf=pe; pe=pe->next; if(NULL==pf->next) { printf("未找到要删除数据\n"); return head; } } if(pe==head) { head=pe->next; free(pe); } else { pf->next=pe->next; free(pe); } } return head; } //*************************过滤链表******************************


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3